// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: AGPL-3.0-or-later

package server

import (
	"apiote.xyz/p/szczanieckiej/api"
	"apiote.xyz/p/szczanieckiej/config"
	"apiote.xyz/p/szczanieckiej/traffic"

	"errors"
	"net/http"
	"time"

	"apiote.xyz/p/gott/v2"
	"git.sr.ht/~sircmpwn/go-bare"
)

type FeedsHandlerVars struct {
	HandlerVars
	feedInfos   map[string]traffic.FeedInfo
	lastUpdates map[string]time.Time
}

func getFeedInfos(v AbstractHandlerVars) (AbstractHandlerVars, error) {
	vv := v.(*FeedsHandlerVars)

	feedInfos, lastUpdates, err := traffic.GetFeedInfos(v.getTraffic(), v.getConfig())

	vv.feedInfos = feedInfos
	vv.lastUpdates = lastUpdates
	return vv, err
}

func makeFeedsResponse(v AbstractHandlerVars) (AbstractHandlerVars, error) {
	vv := v.(*FeedsHandlerVars)

	response, err := api.MakeFeedsResponse(vv.feedInfos, vv.lastUpdates, v.getAccept(), v.getPreferredLanguages())
	v.setResponse(response)
	if err != nil && errors.Is(err, api.AcceptError) {
		err = ServerError{
			code: http.StatusNotAcceptable,
		}
	}

	return vv, err
}

func marshalFeedsResponse(v AbstractHandlerVars) (AbstractHandlerVars, error) {
	r := v.getResponse().(api.FeedsResponse)
	bytes, err := bare.Marshal(&r)
	v.setResponseBytes(bytes)
	return v, err
}

func handleFeeds(w http.ResponseWriter, r *http.Request, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
	handlerVars := &FeedsHandlerVars{
		HandlerVars: HandlerVars{
			w: w,
			r: r,
			t: t,
			c: cfg,
			a: accept,
		},
	}
	result := gott.R[AbstractHandlerVars]{
		S: handlerVars,
	}
	result = result.
		Map(getAcceptLanguage).
		Bind(parseAcceptLanguage).
		Bind(getFeedInfos).
		Bind(makeFeedsResponse).
		Bind(marshalFeedsResponse).
		Tee(writeResponse)

	return result.E
}
